/*
 * Galaxium Messenger
 * Copyright (C) 2003-2007 Philippe Durand <draekz@gmail.com>
 * Copyright (C) 2007 Ben Motmans <ben.motmans@gmail.com>
 * Copyright (C) 2007 Paul Burton <paulburton89@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.IO;

using Galaxium.Core;
using Galaxium.Gui;
using Galaxium.Gui.GtkGui;
using Galaxium.Protocol;

using Anculus.Core;

using Gtk;
using Glade;

namespace Galaxium.AdiumThemes
{
	public class GtkAdiumMessageDisplayPreferences: IMessageDisplayPreferences
	{
		private IConfigurationSection _config;

		[Widget("styleBox")] VBox _styleBox;
		[Widget("variantBox")] VBox _variantBox;
		[Widget("swDisplay")] ScrolledWindow _swDisplay;
		
		ImageComboBox<AdiumMessageStyle> _comboStyle;
		ImageComboBox<string> _comboVariant;
		
		AdiumMessageStyle _style;
		string _variant;
		
		AdiumMessageDisplay _display;
		
		Viewport _nativeWidget;
		public object Widget { get { return _nativeWidget; } }
			
		public GtkAdiumMessageDisplayPreferences()
		{
			XML.CustomHandler = new XMLCustomWidgetHandler(CreateCustomWidget);
			Widget gladeWidget = GladeUtility.ExtractWidget<Widget> (GladeUtility.GetGladeResourceStream (this.GetType().Assembly, "GtkAdiumMessageDisplayPreferences.glade"), "widget", this);
			
			_nativeWidget = new Viewport ();
			_nativeWidget.BorderWidth = 0;
			_nativeWidget.ShadowType = ShadowType.None;
			_nativeWidget.Add (gladeWidget);
			
			_config = Configuration.MessageDisplay.Section["Adium"];
			
			ExampleSession.Init ();
			
			try
			{
				_display = new AdiumMessageDisplay(new ExampleConversation ());
				_swDisplay.Add((Widget)_display.Widget);
			}
			catch (Exception ex)
			{
				Log.Error (ex, "Unable to create message display");
				_swDisplay.AddWithViewport (new Label ("Unable to create Adium message display"));
			}
			
			_comboVariant = new ImageComboBox<string>(new ImageComboTextLookup<string>(VariantTextLookup), new ImageComboPixbufLookup<string>(VariantImageLookup));
			_variantBox.PackStart(_comboVariant, false, true, 0);
			_comboVariant.Changed += VariantChanged;
			
			_comboStyle = new ImageComboBox<AdiumMessageStyle>(new ImageComboTextLookup<AdiumMessageStyle>(StyleTextLookup), new ImageComboPixbufLookup<AdiumMessageStyle>(StyleImageLookup));
			_styleBox.PackStart(_comboStyle, false, true, 0);
			_comboStyle.Changed += StyleChanged;
			
			foreach (AdiumMessageStyle style in AdiumMessageStyleFactory.Styles)
			{
				_comboStyle.Append(style);
				
				if (Path.GetFileName (style.ArchiveFilename) == _config.GetString("Style"))
					_comboStyle.Select(style);
			}
			
			if (_comboStyle.GetSelectedItem() == null)
				_comboStyle.SelectFirst();
			
			_nativeWidget.ShowAll();
			
			_nativeWidget.Unrealized += delegate
			{
				if (_swDisplay.Child != null)
					_swDisplay.Remove(_swDisplay.Child);
			};
		}
		
		private void StyleChanged (object sender, EventArgs args)
		{
			_style = _comboStyle.GetSelectedItem();
			
			AdiumMessageStyleFactory.ActiveStyle = _style;
			
			_comboVariant.Clear();
			
			foreach (string variant in _style.Variants)
			{
				_comboVariant.Append(variant);
				
				if (variant == _config.GetString("Variant"))
					_comboVariant.Select(variant);
			}
			
			if (_style.Variants.Count == 0)
				_comboVariant.Append (_style.DisplayNameForNoVariant);
			
			if (string.IsNullOrEmpty(_comboVariant.GetSelectedItem()))
				_comboVariant.SelectFirst();
		}
		
		private string StyleTextLookup(AdiumMessageStyle item)
		{
			return GLib.Markup.EscapeText(item.Name);
		}

		private Gdk.Pixbuf StyleImageLookup(AdiumMessageStyle item)
		{
			return IconUtility.GetIcon ("galaxium-preferences-themes", IconSizes.Small);
		}
		
		private void VariantChanged (object sender, EventArgs args)
		{
			_variant = _comboVariant.GetSelectedItem();
			
			AdiumMessageStyleFactory.ActiveVariant = _variant;
			
			if (_display != null)
			{
				_display.Style = _style;
				_display.Variant = _variant;
			}
			
			AddExampleMessages();
		}
		
		private string VariantTextLookup(string item)
		{
			return GLib.Markup.EscapeText(item);
		}

		private Gdk.Pixbuf VariantImageLookup(string item)
		{
			return IconUtility.GetIcon ("galaxium-preferences-themes", IconSizes.Small);
		}
		
		void AddExampleMessages()
		{
			if (_display != null)
			{
				_display.AddSystemMessage("This is a system message");
				_display.AddMessage(new TextMessage(ExampleSession.inst.Account, DateTime.Now, "This is an outgoing message"));
				_display.AddMessage(new TextMessage(ExampleContact.inst, DateTime.Now, "This is an incoming message"));
			}
		}
			
		private Widget CreateCustomWidget (XML gxml, string func_name, string name, string string1, string string2, int int1, int int2)
		{
			return new Label("ERROR");
		}
	}
	
	class ExampleConversation : AbstractConversation
	{
		public ExampleConversation ()
			: base (ExampleContact.inst, ExampleSession.inst)
		{
		}
		
		public override void InviteContact (IContact contact) { }
		public override void Close () { }
		protected override bool RequestLoggerIfNeeded (bool logEvent) { return false; }
	}
	
	class ExampleSession : AbstractSession
	{
		public static ExampleSession inst;
		
		public static void Init ()
		{
			if (inst == null)
				inst = new ExampleSession ();
		}
		
		private ExampleSession ()
			: base (new ExampleAccount ())
		{
			ExampleContact.inst = new ExampleContact (this);
		}
		
		public override ContactCollection ContactCollection { get { return null; } }
		public override void SetPresence (BasePresence presence) { }
		public override void Connect () { }
		public override void Disconnect () { }
	}
	
	class ExampleAccount : AbstractAccount
	{
		public ExampleAccount ()
			: base (null, "owner@somewhere.com")
		{
			DisplayName = "Example Account";
		}
		
		public override IProtocol Protocol { get { return ExampleProtocol.inst; } }
	}
	
	class ExampleContact: AbstractContact
	{
		public static ExampleContact inst;
		
		public ExampleContact (ExampleSession session)
			: base (session, "contact@somewhere.com", "Example Contact", null)
		{
			base.Logging = false;
		}
	}
	
	class ExampleProtocol: AbstractProtocol
	{
		public static ExampleProtocol inst = new ExampleProtocol ();
		
		public ExampleProtocol ()
		{
		}
		
		public override string Image { get { return string.Empty; } }
		public override string Name { get { return "Protocol"; } }
		public override string Description { get { return string.Empty; } }
	}
}
